# 中断和异常处理函数

.global trap_vector
.align 4

trap_vector:
        # make room to save registers.
        addi sp, sp, -256
        # save the registers.
        sd ra, 0(sp)
        sd sp, 8(sp)
        sd gp, 16(sp)
        sd tp, 24(sp)
        sd t0, 32(sp)
        sd t1, 40(sp)
        sd t2, 48(sp)
        sd s0, 56(sp)
        sd s1, 64(sp)
        sd a0, 72(sp)
        sd a1, 80(sp)
        sd a2, 88(sp)
        sd a3, 96(sp)
        sd a4, 104(sp)
        sd a5, 112(sp)
        sd a6, 120(sp)
        sd a7, 128(sp)
        sd s2, 136(sp)
        sd s3, 144(sp)
        sd s4, 152(sp)
        sd s5, 160(sp)
        sd s6, 168(sp)
        sd s7, 176(sp)
        sd s8, 184(sp)
        sd s9, 192(sp)
        sd s10, 200(sp)
        sd s11, 208(sp)
        sd t3, 216(sp)
        sd t4, 224(sp)
        sd t5, 232(sp)
        sd t6, 240(sp)

        # call the trap handler in trap.c
        call trap_kernel

        # restore registers.
        ld ra, 0(sp)
        ld sp, 8(sp)
        ld gp, 16(sp)
        # not tp (contains hartid), in case we moved CPUs
        ld t0, 32(sp)
        ld t1, 40(sp)
        ld t2, 48(sp)
        ld s0, 56(sp)
        ld s1, 64(sp)
        ld a0, 72(sp)
        ld a1, 80(sp)
        ld a2, 88(sp)
        ld a3, 96(sp)
        ld a4, 104(sp)
        ld a5, 112(sp)
        ld a6, 120(sp)
        ld a7, 128(sp)
        ld s2, 136(sp)
        ld s3, 144(sp)
        ld s4, 152(sp)
        ld s5, 160(sp)
        ld s6, 168(sp)
        ld s7, 176(sp)
        ld s8, 184(sp)
        ld s9, 192(sp)
        ld s10, 200(sp)
        ld s11, 208(sp)
        ld t3, 216(sp)
        ld t4, 224(sp)
        ld t5, 232(sp)
        ld t6, 240(sp)

        addi sp, sp, 256

        sret


# .global timer_vector
# .align 4
# # 在M-mode完成timercmp寄存器重装
# # 具体的时钟中断处理留给S-mode软件中断
# timer_vector:
#         # timer.c中定义了数组 uint64 scratch[5] 
#         # 该数组地址存放于mscratch寄存器
#         # 其中前三个位置是寄存器临时存放空间
#         # 第四个位置是 CLINT TIMERCMP 寄存器的映射地址
#         # 第五个位置是 TIMER_INTERVAL 中断时间间隔
        
#         # swap (a0,mscratch) 把a1,a2,a3暂存到数组中
#         csrrw a0, mscratch, a0
#         sd a1, 0(a0)
#         sd a2, 8(a0)
#         sd a3, 16(a0)

#         # a1 = &timercmp; a2 = interval; a3 = timercmp;  
#         ld a1, 24(a0) 
#         ld a2, 32(a0)
#         ld a3, 0(a1)
#         # 更新下一次时钟中断触发点(修改TIMERCMP)
#         add a3, a3, a2
#         sd a3, 0(a1)
#         # 在当前执行流返回S-mode时触发软件中断(SSIP = 1)
#         # 为什么不使用STIP呢? 因为那是不可写的
#         li a1, 2
#         csrw sip, a1
        
#         # 恢复这些寄存器原来的状态
#         ld a3, 16(a0);
#         ld a2, 8(a0);
#         ld a1, 0(a0);
#         csrrw a0, mscratch, a0

#         mret